from wsgiref.util import request_uri

from django.shortcuts import redirect
from django.utils.deprecation import MiddlewareMixin
from web import models
import datetime

class Tracer(object):
    def __init__(self):
        self.user = None
        self.price_policy = None
        self.project = None

class AuthMiddleware(MiddlewareMixin):
    # 先执行这个process_request，并且通过后再执行路由匹配，匹配成功后才执行process_view，执行完process_view后才执行视图函数
    def process_request(self,request):

        tracer_object = Tracer()
        user_id = request.session.get('user_id',0) ## 有数值则获取数值，无数值则user_id=0。用户登录的时候设置的这个session
        user_object = models.UserInfo.objects.filter(id=user_id).first()
        tracer_object.user = user_object
        request.tracer = tracer_object ## 数据库中查不到对象时request.tracer=None
        ## 添加中间件的白名单
        if request.path_info in ['/web/index/','/web/register/','/web/login/','/web/image/code/','/web/send/sms/',
                                 '/web/login/','/web/login/sms/','/web/logout/','/web/price/','/web1/register/']:
            return None
        if not request.tracer.user:
            return redirect('/web/login/')

        ## 登录成功后，访问后台管理时，获取当前用户所拥有的额度
        """
            方式一：免费额度在交易记录中存储。首先在交易表中通过用户对象user_object，来获取这个用户所有的交易表中的记录。
            如果一个用户有多次的交易记录，那么最后一次的记录是最准确的，所以用id的降序来获取第一条记录就是这个用户最后一次的交易记录
            并且这个用户交易记录的交易状态必须是已经支付的即：status=2
        """
        _object = models.Transaction.objects.filter(user=user_object,status=2).order_by('-id').first()
        ## 获取交易记录对象的结束时间：end_datetime，当结束时间小于当前时间的话则证明这个额度已经过期
        current_datetime = datetime.datetime.now()

        if _object.end_datetime is not None and _object.end_datetime < current_datetime: ## 对象有结束时间，并且结束时间小于当前时间则证明已经过期
            """
            一：免费的额度在交易记录中获取
                如果用户的额度已经过期，那么会自动变成免费版的额度，所以额度过期时可以直接获取用户在注册时拥有的免费版的额度就行
                方法一：获取id最小的数据即注册时的第一条免费版额度的数据
                _object = models.Transaction.objects.filter(user=user_object, status=2).order_by('id').first()
                方法二：在交易记录表中price_policy是价格策略表的外键，所以可以用：外键_主键表属性，来获取属于这个价格策略的的数据
                _object = models.Transaction.objects.filter(user=user_object, status=2，price_policy_category=1).first()
            """
            _object = models.Transaction.objects.filter(user=user_object, status=2,price_policy_categor = 1).first()
            # ## 可以给request添加一个属性，并给这个属性赋值为查询出来的价格策略表的对象，后面在别的函数中就可以用request.添加的属性来获取对象的各个数据
            # request.transaction = _object
            ## 也可以直接添加request的额度字段
            tracer_object.price_policy = _object.price_policy
            # request.tracer = tracer_object
        else: ## 如果最终时间为空或者最终时间不小于当前时间，那么继续把现在的价格策略赋值给对象tracer_object
            tracer_object.price_policy = _object.price_policy
            # request.price_policy = tracer_object
            """
            二：免费的额度储存在配置文件中
                还是获取交易记录表中ID值最大的数据，这个就代表最新的交易额度。如果获取不到数据就说明用户没有购买额度，用户使用的是免费版的额度
            """
            # _object = models.Transaction.objects.filter(user=user_object, status=2).order_by('-id').first()
            # if not _object:
            #     # 对象_object没有数据，就说明用户使用的是免费版的额度，所以直接获取价格策略中的免费额度就可以了
            #     request.price_policy = models.PricePolicy.objects.filter(category=1,title='个人免费版').first()
            # else:
            #     # 已经购买了付费版,再判断下额度是否过期
            #     current_datetime = datetime.datetime.now()
            #     if _object.end_datetime and _object.end_datetime < current_datetime:
            #         request.price_policy = models.PricePolicy.objects.filter(category=1, title='个人免费版').first()
            #     else:
            #         request.price_policy = _object.price_policy

    ## 通过中间件判断url是否以manage开头，项目id是否为登录用户创建的项目或者是参与的项目。上面的process_request全部通过了，
    # 匹配上路由了才开始执行这个函数即运行了前面的process_request，所以就可以获取到url中携带的参数：project_id的数据了
    def process_view(self,request,view,args,kwargs):
        # 判断url是否以manage开头，如果不是manager口头的，将不再继续往下判断，如果是的话那么将继续往下判断项目是不是用户创建和参与的项目。
        if not request.path_info.startswith('/web/manager/'):
            return
        # 获取url中携带的project_id的数值
        project_id = kwargs.get('project_id')
        # 判断是否是登录用户创建的项目，并获取项目对象
        project_object = models.Project.objects.filter(creator=request.tracer.user,id=project_id).first()
        if project_object:
            request.tracer.project = project_object
            return
        # 再判断，是否是登录用户参与的项目
        project_user_object = models.ProjectUser.objects.filter(user=request.tracer.user,project_id=project_id).first()
        if project_user_object:
            request.tracer.project = project_user_object.project
            return
        return redirect('project_list')



















